/**
 * Copyright (c) 2016-2019 人人开源 All rights reserved.
 *
 * https://www.renren.io
 *
 * 版权所有，侵权必究！
 */

package io.renren.modules.project.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.lettuce.core.RedisClient;
import io.lettuce.core.RedisURI;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.api.sync.RedisCommands;
import io.renren.common.utils.PageUtils;
import io.renren.modules.project.dao.DatasourceDao;
import io.renren.modules.project.dao.ServiceConfigDao;
import io.renren.modules.project.entity.DataObject;
import io.renren.modules.project.entity.DatasourceEntity;
import io.renren.modules.project.entity.ServiceConfigEntity;
import io.renren.modules.project.service.DatasourceService;
import io.renren.modules.project.service.ModuleService;
import io.renren.modules.systemconfig.dao.SysConfigServerDao;
import io.renren.modules.systemconfig.entity.SystemConfigServersEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestParam;

import java.nio.charset.StandardCharsets;
import java.sql.*;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import java.util.*;


/**
 * 系统用户
 *
 * @author Mark sunlightcs@gmail.com
 */
@Service("datasourceService")
public class DatasourceServiceImpl extends ServiceImpl<DatasourceDao, DatasourceEntity> implements DatasourceService {

	@Autowired
	private SysConfigServerDao serverMapper;

	@Autowired
	private ModuleService moduleService;

	@Override
	public PageUtils queryPage(Map<String, Object> params) {
		String key = (String)params.get("key");
		Long  current = Long.parseLong((String)params.get("page"));
		Long size = Long.parseLong((String)params.get("limit"));
		List<DatasourceEntity> records = this.baseMapper.selectEntityPage(key,size*(current-1),size*current);
		IPage<DatasourceEntity> page = new Page<>(current, size, this.baseMapper.selectRecordSize(key));
		page.setRecords(records);
		return new PageUtils(page);
	}

	@Override
	public List<DatasourceEntity> findAlllistInfo() {
		return  this.baseMapper.findeAll();
	}

	@Override
	public DatasourceEntity getAllInfo(Long id) {
		DatasourceEntity de=this.baseMapper.selectById(id);
		if(de!=null&&de.getServerId()>0){
			de.setServer(serverMapper.selectById(de.getServerId()));
		}
		return de;
	}

	@Override
	public List findDatalistById(long id,long projectId) throws Exception {
		List<HashMap> datasources = moduleService.selectModuleDatasourceListByProjectIdAndDatasourceId(projectId,id);
		List<DataObject> result  = new ArrayList<>();
		for(HashMap<String,Object> map: datasources){
			if("mysql".equals(map.get("datasource_type"))){
				System.out.println("jdbc:mysql://"+map.get("serverIpaddr")+":"+map.get("port")+"/"+map.get("db_name"));
				Connection com = DriverManager.getConnection("jdbc:mysql://"+map.get("serverIpaddr")+":"+map.get("port")+"/"+map.get("db_name"), (String)map.get("login_name"), (String)map.get("password"));
				Statement stat = com.createStatement();
				String sql = "show tables";
				ResultSet rs = stat.executeQuery(sql);
				while (rs.next()){
					DataObject d_o = new DataObject();
					d_o.setTableName(rs.getString("Tables_in_"+map.get("db_name")) );
					d_o.setDataSourceId(id);
					d_o.setDbName((String)map.get("db_name"));
					result.add(d_o);
				}
				rs.close();
				stat.close();
				com.close();
			}else if("redis".equals(map.get("datasource_type"))){
				RedisURI redisUri = RedisURI.builder()
						.withHost((String)map.get("serverIpaddr")).withPort((int)map.get("port")).withPassword(((String)map.get("password")).toCharArray())
						.withTimeout(Duration.of(10, ChronoUnit.SECONDS))
						.build();
				RedisClient client = RedisClient.create(redisUri);
				StatefulRedisConnection<String, String>  connection = client.connect();
				RedisCommands<String, String> commands = connection.sync();
				System.out.println(JSONObject.toJSONString(commands));
				List<String> keyList = commands.keys("*");
				for(String key:keyList){
					DataObject d_o = new DataObject();
					d_o.setTableName(key);
					d_o.setDataSourceId(id);
					result.add(d_o);
				}
				connection.close();
				client.shutdown();
			}
		}
		return result;
	}

	@Override
	public PageUtils findTableDatalist(DataObject dob)  throws Exception {
		DatasourceEntity dse = this.getAllInfo(dob.getDataSourceId());
		List result = new ArrayList<>();
		if("mysql".equals(dse.getDatasourceType())){
			Connection com = DriverManager.getConnection("jdbc:mysql://"+dse.getServer().getIpAddr()+":"+dse.getPort()+"/"+dob.getDbName(), dse.getLoginName(), dse.getPassword());
			Statement stat = com.createStatement();
			String sql = "select * from "+dob.getTableName()+" limit "+dob.getLimit()*(dob.getPage()-1)+","+dob.getLimit()*dob.getPage();
			ResultSet rs = stat.executeQuery(sql);
			while (rs.next()){
				ResultSetMetaData rsmd = rs.getMetaData();
				HashMap hm = new HashMap();
				int count = rsmd.getColumnCount();// 获取列的数量
				for (int i = 1; i <= count; i++) {
					hm.put(rsmd.getColumnName(i), rs.getObject(i));
				}
				result.add(hm);
			}
			rs.close();
			long totalcount= 0;
			sql = "select count(1) as totalcount from "+dob.getTableName();
			rs = stat.executeQuery(sql);
			while (rs.next()) {
				totalcount=rs.getLong("totalcount");
			}
			stat.close();
			com.close();

			IPage page = new Page(dob.getPage(), dob.getLimit(),totalcount );
			page.setRecords(result);
			return  new PageUtils(page);
		}else if("redis".equals(dse.getDatasourceType())){
			RedisURI redisUri = RedisURI.builder()
					.withHost(dse.getServer().getIpAddr()).withPort(dse.getPort()).withPassword(dse.getPassword().toCharArray())
					.withTimeout(Duration.of(10, ChronoUnit.SECONDS))
					.build();
			RedisClient client = RedisClient.create(redisUri);
			StatefulRedisConnection<String, String>  connection = client.connect();
			RedisCommands<String, String> commands = connection.sync();
			System.out.println(JSONObject.toJSONString(commands));
			DataObject d_o = new DataObject();
			result.add(commands.get(dob.getTableName()));
			connection.close();
			client.shutdown();
			IPage page = new Page(0, 0,0 );
			page.setRecords(result);
			return  new PageUtils(page);
		}
		return null;
	}

	@Override
	public List<DatasourceEntity> getListByServerId(Long id) {
		return this.baseMapper.selectList(new QueryWrapper<DatasourceEntity>().eq("server_id",id));
	}

	@Override
	public DatasourceEntity queryByKey(String key) {
		return baseMapper.queryByKey(key);
	}

	@Override
	@Transactional
	public void saveEntity(DatasourceEntity entity) {
		this.baseMapper.insert(entity);
	}

	@Override
	@Transactional
	public void update(DatasourceEntity user) {
		this.updateById(user);
	}

	@Override
	public void deleteBatch(Long[] userId) {
		this.removeByIds(Arrays.asList(userId));
	}




}